#include <linux/percpu.h>

#include "../inc/tick.h"

/*
 * Tick devices
 */
DEFINE_PER_CPU(struct tick_device, tick_cpu_device) = {};

static int tick_do_timer_cpu = 0;

static void tick_setup_device(struct tick_device *td,
			      struct clock_event_device *newdev, int cpu,
			      const struct cpumask *cpumask)
{
    td->evtdev = newdev;

	if (td->mode == TICKDEV_MODE_PERIODIC)
		tick_setup_periodic(newdev, 0);
}

struct clock_event_device *this_clock_event(void)
{
    struct tick_device *td = this_cpu_ptr(&tick_cpu_device);

    return td->evtdev;
}

bool tick_check_replacement(struct clock_event_device *curdev,
			    struct clock_event_device *newdev)
{
    return true;
}

/*
 * Check, if the new registered device should be used. Called with
 * clockevents_lock held and interrupts disabled.
 */
void tick_check_new_device(struct clock_event_device *newdev)
{
	struct clock_event_device *curdev;
	struct tick_device *td;
	int cpu;

	cpu = smp_processor_id();
	td = &per_cpu(tick_cpu_device, cpu);
	curdev = td->evtdev;

    if (tick_check_replacement(curdev, newdev))
    {
        tick_setup_device(td, newdev, cpu, NULL); //todo
    }

    newdev->event_handler = tick_handle_periodic;
}

/**
 * tick_is_oneshot_available - check for a oneshot capable event device
 */
bool tick_is_oneshot_available(void)
{
	struct clock_event_device *dev = this_clock_event();
    bool ret = true;

	if (!dev || !(dev->features & CLOCK_EVT_FEAT_ONESHOT))
		ret = false;

	return ret;
}

int __tick_do_timer_cpu(void)
{
    return READ_ONCE(tick_do_timer_cpu);
}
